﻿using System;
using System.Linq;
using log4net;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Workflow;

namespace SharePoint.Orm.Helpers {
	public class SPWorkflowHelper {
		private static readonly ILog _log = LogManager.GetLogger(typeof(SPWorkflowHelper));

		public static SPWorkflow GetActiveSPWorkflow(SPListItem listItem) {
			SPWorkflow wf = listItem.Workflows.Cast<SPWorkflow>().OrderByDescending(w => w.Created).FirstOrDefault();
			if (_log.IsDebugEnabled) {
				if (wf == null) {
					_log.Debug("no active workflow found");
				} else {
					_log.Debug("active workflow found (InstanceId:" + wf.InstanceId + ")");
				}
			}
			return wf;
		}

		public static SPWorkflowTask GetActiveTask(SPListItem listItem) {
			SPWorkflow workflow = GetActiveSPWorkflow(listItem);
			if(workflow == null) {
				return null;
			}
			SPWorkflowTask task =
				workflow.Tasks.Cast<SPWorkflowTask>().FirstOrDefault(
					t => !t[SPBuiltInFieldId.TaskStatus].ToString().Equals("Completed"));
			if (_log.IsDebugEnabled) {
				if (task == null) {
					_log.Debug("no active task found");
				} else {
					_log.Debug("active task found (id:" + task.ID + ")");
				}
			}
			return task;
		}

		public static void EnsureStarted(SPWorkflowManager workflowManager, SPListItem listItem, string workflowName, string eventData) {
			_log.Debug("checking to see if workflow is started");
			if (listItem.Workflows.Cast<SPWorkflow>().Any(w => (w.InternalState & SPWorkflowState.Running) == SPWorkflowState.Running)) {
				_log.Debug("workflow already running");
				return;
			}
			SPWorkflowAssociation wfa = listItem.ParentList.WorkflowAssociations
				.Cast<SPWorkflowAssociation>()
				.FirstOrDefault(wa => wa.Name == workflowName);
			if (wfa == null) {
				throw new NullReferenceException("could not find workflow '" + workflowName + "' on list '" + listItem.ParentList.Title + "'");
			}
			if (_log.IsDebugEnabled) {
				_log.Debug("starting workflow '" + wfa.Name + "' on list item id " + listItem.ID);
			}
			workflowManager.StartWorkflow(listItem, wfa, eventData);
			_log.Debug("workflow started");
		}

		public static void EnsureStarted(SPWorkflowManager workflowManager, SPListItem listItem, string workflowName) {
			const string eventData = "<root/>";
			EnsureStarted(workflowManager, listItem, workflowName, eventData);
		}
	}
}
